package com.ikas.ai.server.module.condition.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ikas.ai.server.error.BusinessException;
import com.ikas.ai.server.module.condition.dao.WorkConditionFlowDao;
import com.ikas.ai.server.module.condition.dto.WorkConditionFlowDTO;
import com.ikas.ai.server.module.condition.dto.WorkConditionStepDTO;
import com.ikas.ai.server.module.condition.dto.WorkConditionStepDetailDTO;
import com.ikas.ai.server.module.condition.model.WorkConditionFlow;
import com.ikas.ai.server.module.condition.model.WorkConditionStep;
import com.ikas.ai.server.module.condition.model.WorkConditionStepDetail;
import com.ikas.ai.utils.BeanUtils;
import com.ikas.ai.utils.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: 工况流程Service
 * @Author: qi.yilai
 * @Date: 2023/4/13 10:04
 * @Version: 1.0.0
 **/
@Service
@Slf4j
public class WorkConditionFlowService extends ServiceImpl<WorkConditionFlowDao, WorkConditionFlow> {

    @Autowired
    private WorkConditionStepService workConditionStepService;

    @Autowired
    private WorkConditionStepDetailService workConditionStepDetailService;

    /**
     * 获取工况模板
     *
     * @param wfName
     * @return
     */
    public WorkConditionFlowDTO findWorkConditionFlowConfiguration(String machineNo, String wfName) {
        LambdaQueryWrapper<WorkConditionFlow> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WorkConditionFlow::getMachineNo, machineNo);
        lambdaQueryWrapper.eq(WorkConditionFlow::getWfName, wfName);
        //启用的流程才触发工况流程
        lambdaQueryWrapper.eq(WorkConditionFlow::getState, 1);
        WorkConditionFlow workConditionFlow = baseMapper.selectOne(lambdaQueryWrapper);
        if (Objects.isNull(workConditionFlow)) {
            throw new BusinessException(String.format(Locale.ENGLISH, "%s不存在启用的工况流程配置", wfName));
        }
        WorkConditionFlowDTO workConditionFlowDTO = BeanUtils.convert(workConditionFlow, WorkConditionFlowDTO.class);
        List<WorkConditionStep> steps = workConditionStepService.getWorkConditionStepByWfId(workConditionFlow.getId());
        if (CollectionUtil.isEmpty(steps)) {
            throw new BusinessException(String.format(Locale.ENGLISH, "%s工况步骤为空", wfName));
        }
        List<WorkConditionStepDTO> stepDTOS = BeanUtils.convert(steps, WorkConditionStepDTO.class);
        List<Long> stepIds = steps.stream().map(WorkConditionStep::getId).collect(Collectors.toList());
        Map<Long, List<WorkConditionStepDetail>> stepDetailMap = workConditionStepDetailService.getWorkConditionStepDetailByStepIds(stepIds).stream().collect(Collectors.groupingBy(WorkConditionStepDetail::getStepId));
        if (CollectionUtil.isEmpty(stepDetailMap)) {
            throw new BusinessException(String.format(Locale.ENGLISH, "%s工况步骤详情为空", wfName));
        }

        stepDTOS.stream().forEach(stepDto -> {
            List<WorkConditionStepDetail> list = stepDetailMap.get(stepDto.getId());
            if (!CollectionUtil.isEmpty(list)) {
                List<WorkConditionStepDetailDTO> details = Lists.newArrayList();
                list.forEach(workConditionStepDetail -> {
                    WorkConditionStepDetailDTO workConditionStepDetailDTO = BeanUtils.convert(workConditionStepDetail, WorkConditionStepDetailDTO.class);
                    // BeanUtils 无法转换
                    workConditionStepDetailDTO.setStepName(stepDto.getStepName());
                    workConditionStepDetailDTO.setPMeteCode(workConditionStepDetail.getPMeteCode());
                    workConditionStepDetailDTO.setDetailId(workConditionStepDetailDTO.getId());
                    details.add(workConditionStepDetailDTO);
                });

                stepDto.setDetails(details);
            }
        });

        workConditionFlowDTO.setSteps(stepDTOS);
        return workConditionFlowDTO;
    }

}
